package com.hyperf.spring.boot.autoconfigure.snowflake;

import com.hyperf.core.exception.CustomException;
import com.hyperf.core.snowflake.WorkerRegister;
import com.hyperf.core.snowflake.worker.ZookeeperWorkerRegister;
import org.apache.curator.framework.CuratorFramework;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;

/**
 * 雪花算法ID生成器自动装配
 *
 * @author lizhaoyang
 */
@Configuration
@EnableConfigurationProperties({SnowflakeProperties.class})
@ConditionalOnProperty(prefix = "hyperf.snowflake", name = "enabled", havingValue = "true", matchIfMissing = true)
public class ZookeeperSnowflakeAutoConfiguration implements EnvironmentAware {

    private String applicationName;

    private CuratorFramework curatorFramework;

    public ZookeeperSnowflakeAutoConfiguration(CuratorFramework curatorFramework) {
        this.curatorFramework = curatorFramework;
    }

    @Bean
    @ConditionalOnBean(CuratorFramework.class)
    @ConditionalOnMissingBean(WorkerRegister.class)
    @ConditionalOnProperty(prefix = "hyperf.snowflake", name = "worker-register-type", havingValue = "zookeeper")
    public WorkerRegister zookeeperWorkerRegister() {
        return new ZookeeperWorkerRegister(applicationName, curatorFramework);
    }

    @Override
    public void setEnvironment(Environment environment) {
        String name = environment.getProperty("spring.application.name");
        if (!StringUtils.hasText(name)) {
            throw new CustomException("spring.application.name can not be empty");
        }
        this.applicationName = name;
    }
}
